import "./index.css";
import React, {useCallback, useEffect, useRef, useState} from 'react';
import Panel from "../../components/Panel";
import {Button, Input, Modal, message, notification, Select, Checkbox} from "antd";
import {Controlled as CodeMirror} from "react-codemirror2";
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/lib/codemirror.js';
import 'codemirror/addon/display/fullscreen.js';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/edit/matchbrackets';
import "codemirror/addon/edit/closebrackets";
// import 'codemirror/addon/hint/show-hint';
import '../../utils/show-hint';
// import 'codemirror/addon/hint/javascript-hint';
import '../../utils/js-hint';
import {toSearchParams} from "../../utils";
import {HttpGet, HttpPost, Get} from "../../utils/httpUtil";
import {SuperSelect} from "../../components/SuperSelect";
import ColTypeDrawer from "./ColTypeDrawer";
import {useStoreState, useStoreActions} from 'easy-peasy'
function RuleEdit(props) {
    let actionStore = useStoreActions(actions => {
        return actions
    });
    let ruleS = useStoreState(state => state.RuleData.RuleData)
    const {location} = props;

    const editorRef = useRef();
    const sdEditorRef = useRef();
    const dEditorRef = useRef();
    const sEditorRef = useRef();
    const fEditorRef = useRef();
    const [rule, setRule] = useState({
        title: "",
        author: "",
        version: 0,
        group: "",
        titleColor: "",
        url: "",
        col_type: "",
        class_name: "",
        class_url: "",
        area_name: "",
        area_url: "",
        year_name: "",
        year_url: "",
        sort_name: "",
        sort_url: "",
        find_rule: "",
        search_url: "",
        searchFind: "",
        detail_col_type: "",
        detail_find_rule: "",
        sdetail_col_type: "",
        sdetail_find_rule: "",
        ua: "",
        preRule: "",
    });
    const [FormName, setFormName] = useState('');
    const [ruleImportModalVisible, setRuleImportModalVisible] = useState(false);
    const [ruleImport, setRuleImport] = useState("");
    const [ruleShareModalVisible, setRuleShareModalVisible] = useState(false);
    const [ruleShare, setRuleShare] = useState("");
    const [autoComplete, setAutoComplete] = useState(false);
    const [selectRule, setSelectRule] = useState();
    const [allRules, setAllRules] = useState([]);
    const autoCompleteRef = useRef(false);
    const [detailTypeShow, setDetailTypeShow] = useState(false);
    function onChange(key, value) {
        const ruleNew = {...rule};
        ruleNew[key] = value;
        setRule(ruleNew);
        actionStore.RuleData.addTodo(ruleNew)
    }
    useEffect(() => {
        setRule(ruleS)
    }, [location]);
    // setRule(useStoreState(state => state.RuleData.RuleData))
    function setFormN(key) {
        rule[FormName] = key
        setDetailTypeShow(false)
    }

    // 将表单转化为对象
    function rule2json() {
        const ruleJSON = JSON.parse(JSON.stringify(rule));
        ruleJSON['version'] = parseInt(rule['version']);
        return ruleJSON;
    }

    function clear() {
        setRule({
            title: "",
            author: "",
            version: 0,
            group: "",
            titleColor: "",
            url: "",
            col_type: "",
            class_name: "",
            class_url: "",
            area_name: "",
            area_url: "",
            year_name: "",
            year_url: "",
            sort_name: "",
            sort_url: "",
            find_rule: "",
            search_url: "",
            searchFind: "",
            detail_col_type: "",
            detail_find_rule: "",
            sdetail_col_type: "",
            sdetail_find_rule: "",
            ua: "",
            preRule: "",
        });
        actionStore.RuleData.addTodo(rule)
    }

    function importRule() {
        const rus = ruleImport.split("￥");
        if (rus.length < 3) {
            message.error("口令有误");
            return;
        }
        if (rus[1] !== "home_rule_v2" && rus[1] !== "home_rule") {
            message.error("口令有误，只能是首页规则口令");
            return;
        }
        rus[0] = "";
        rus[1] = "";
        const j = rus.join("￥").substring(2);
        const edit = JSON.parse(j);
        setRule(edit);
        setRuleImport("");
        setRuleImportModalVisible(false);
    }

    function shareRule() {
        const r = "海阔视界规则分享，当前分享的是：首页频道￥home_rule_v2￥" + JSON.stringify(rule);
        setRuleShare(r);
        setRuleShareModalVisible(true);
    }

    function saveRule() {
        (async () => {
            await HttpPost(`/saveRule`, rule2json()).then(json => {
                console.log('推送:', rule2json());
                if (json.isSuccess) {
                    notification.success({message: "保存规则成功", description: "保存规则成功"});
                } else {
                    notification.error({message: "保存规则失败", description: `保存规则失败!\nErrorMsg: ${json.errorMsg}`});
                }
            }).catch(err => {
                notification.error({message: "保存规则失败", description: `保存规则失败,无法连接到「APP」!\n${err}`});
            });
        })();
    }

    const refresh = useCallback(() => {
        if (editorRef.current != null) {
            editorRef.current.refresh();
        }
        if (sdEditorRef.current != null) {
            sdEditorRef.current.refresh();
        }
        if (dEditorRef.current != null) {
            dEditorRef.current.refresh();
        }
        if (sEditorRef.current != null) {
            sEditorRef.current.refresh();
        }
        if (fEditorRef.current != null) {
            fEditorRef.current.refresh();
        }
    }, []);

    function onCursorActivity(editor) {
        if (autoCompleteRef.current) {
            editor.showHint();
        }
    }

    function fetchAndBindRule(ruleTitle) {
        (async () => {
            await Get(`/getRuleContent?title=${ruleTitle}`).then(json => {
                if (json != null && json.length > 0) {
                    const edit = JSON.parse(json);
                    setRule(edit);
                } else {
                    notification.error({message: "获取规则失败", description: `获取规则失败,内容为空`});
                }
            }).catch(err => {
                notification.error({message: "获取规则失败", description: `获取规则失败,无法连接到「APP」!\n${err}`});
            });
        })();
    }

    useEffect(() => {
        autoCompleteRef.current = autoComplete;
    }, [autoComplete]);

    useEffect(() => {        
        refresh();
    }, [rule]);
   
    useEffect(() => {
        const auto = localStorage.getItem("autoComplete");
        if (auto != null && auto === "true") {
            setAutoComplete(true);
        }
    }, []);

    useEffect(() => {
        if (ruleImportModalVisible) {
            setRuleImport("");
        }
    }, [ruleImportModalVisible]);

    useEffect(() => {
        if (selectRule != null && selectRule.length > 0) {
            fetchAndBindRule(selectRule);
        }
    }, [selectRule]);

    useEffect(() => {
        (async () => {
            await HttpGet(`/getAllRuleTitles`).then(json => {
                if (json != null && json.length > 0) {
                    setAllRules(json);
                }
            }).catch(err => {
                notification.error({message: "获取规则失败", description: `获取规则失败,无法连接到「APP」!\n${err}`});
            });
        })();
    }, []);

    useEffect(() => {
        const params = toSearchParams(location);
        try {
            const ruleTitle = params.get("rule");
            if (ruleTitle != null && ruleTitle.length > 0) {
                setSelectRule(ruleTitle);
                fetchAndBindRule(ruleTitle);
            }
        } catch (e) {
        }
    }, [location]);

    const codeMirrorOpt = {
        lineNumbers: true,
        lineWrapping: true,
        smartIndent: true,
        mode: {name: "javascript"},
        matchBrackets: true,
        autoCloseBrackets: true,
        showHint: true,
        indentWithTabs: true,
        extraKeys: {Tab: 'autocomplete'},
        hintOptions: {
            completeSingle: false,
        },
    };

    return (
        <div>
            <div style={{
                width: 120,
                overflow: 'auto',
                height: '100vh',
                position: 'fixed',
                right: 0,
                marginRight: 20
            }}>
                <div style={{marginBottom: 10}}><Button type={"primary"} onClick={saveRule}>保存规则</Button></div>
                <div style={{marginBottom: 10}}><Button onClick={shareRule}>生成口令</Button></div>
                <div style={{marginBottom: 10}}><Button onClick={() => setRuleImportModalVisible(true)}>口令导入</Button>
                </div>
                <div style={{marginBottom: 10}}><Button onClick={clear}>清空表单</Button></div>
                <div style={{marginBottom: 10}}><Button onClick={() => setDetailTypeShow(true)}>样式示例</Button></div>
            </div>
            <div style={{marginRight: 120}}>

                <div className={"mail-edit-head-bg"}>
                    <h3 className={"head-title"}>选择规则：</h3>
                    <SuperSelect
                        optionFilterProp="children"
                        showSearch={true}
                        dropdownMatchSelectWidth={false}
                        className={"super-select"}
                        value={selectRule}
                        onSelect={setSelectRule}>
                        {allRules.map(rule => <Select.Option value={rule}>{rule}</Select.Option>)}
                    </SuperSelect>
                </div>

                <Panel title='基础信息' titleIcon='api'>
                    <div style={{padding: 15}}>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>规则名称：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"规则名称"}
                                value={rule.title}
                                onChange={(e) => onChange("title", e.target.value)}/>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>规则作者：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"规则作者（author）"}
                                value={rule.author}
                                onChange={(e) => onChange("author", e.target.value)}/>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>规则版本：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"规则版本（version）"}
                                value={rule.version}
                                onChange={(e) => onChange("version", e.target.value)}/>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>频道分组：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"频道分组（名称前加①、②等序号可排序）"}
                                value={rule.group}
                                onChange={(e) => onChange("group", e.target.value)}/>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>字体颜色：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"频道名称字体颜色（可不填）"}
                                value={rule.titleColor}
                                onChange={(e) => onChange("titleColor", e.target.value)}/>
                        </div>
                    </div>
                </Panel>

                <Panel title='基础规则' titleIcon='api'>
                    <div style={{padding: 15}}>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>频道链接：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 3}}
                                placeholder={"频道链接（可不填，可只填搜索相关内容）"}
                                value={rule.url}
                                onChange={(e) => onChange("url", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>显示样式：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"显示样式（col_type）"}
                                value={rule.col_type}
                                onClick={(e) => setFormName('col_type')}
                                onChange={(e) => onChange("col_type", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>分类名称：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"分类名称（class_name）"}
                                value={rule.class_name}
                                onChange={(e) => onChange("class_name", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>分类替换：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"分类替换词（class_url）"}
                                value={rule.class_url}
                                onChange={(e) => onChange("class_url", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>地区名称：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"地区名称（area_name）"}
                                value={rule.area_name}
                                onChange={(e) => onChange("area_name", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>地区替换：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"地区替换词（area_url）"}
                                value={rule.area_url}
                                onChange={(e) => onChange("area_url", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>年代名称：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"年代名称（year_name）"}
                                value={rule.year_name}
                                onChange={(e) => onChange("year_name", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>年代替换：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"年代替换词（year_url）"}
                                value={rule.year_url}
                                onChange={(e) => onChange("year_url", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>排序名称：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"排序名称（sort_name）"}
                                value={rule.sort_name}
                                onChange={(e) => onChange("sort_name", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>排序替换：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"排序替换（sort_url）"}
                                value={rule.sort_url}
                                onChange={(e) => onChange("sort_url", e.target.value)}/>
                        </div>


                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>搜索链接：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 5}}
                                placeholder={"搜索链接（search_url，用**作为关键词占位符）"}
                                value={rule.search_url}
                                onChange={(e) => onChange("search_url", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>二级样式：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"二级样式（detail_col_type）"}
                                value={rule.detail_col_type}
                                onClick={(e) => setFormName('detail_col_type')}
                                onChange={(e) => onChange("detail_col_type", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>搜二样式：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"搜索二级列表显示样式（sdetail_col_type）"}
                                value={rule.sdetail_col_type}
                                onClick={(e) => setFormName('sdetail_col_type')}
                                onChange={(e) => onChange("sdetail_col_type", e.target.value)}/>
                        </div>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>全局UA：</h3>
                            <Input.TextArea
                                className={"mail-input"}
                                autoSize={{minRows: 1, maxRows: 1}}
                                placeholder={"规则全局UA（以url里面的ua优先，为空默认mobile，可选auto/mobile/pc）"}
                                value={rule.ua}
                                onChange={(e) => onChange("ua", e.target.value)}/>
                        </div>

                    </div>
                </Panel>

                <Panel title='解析规则' titleIcon='api' subTitle={<span>Tips：按Tab键可以自动补全代码
                    <Checkbox checked={autoComplete} onChange={e => {
                        localStorage.setItem("autoComplete", e.target.checked + "");
                        setAutoComplete(e.target.checked);
                    }}
                              style={{marginLeft: 10}}>动态补全</Checkbox></span>}>
                    <div style={{padding: 15}}>

                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>解析规则：</h3><span>（列表;标题;图片;描述;链接）</span>
                            <div className={"code-mirror-bg"}>
                                <CodeMirror
                                    onCursorActivity={onCursorActivity}
                                    className={"code-mirror"}
                                    value={rule.find_rule}
                                    options={codeMirrorOpt}
                                    onBeforeChange={(editor, data, value) => onChange("find_rule", value)}
                                    editorDidMount={editor => {
                                        fEditorRef.current = editor;
                                    }}
                                />
                            </div>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>搜索解析：</h3><span>（列表;标题;链接;描述;详情;图片）</span>
                            <div className={"code-mirror-bg"}>
                                <CodeMirror
                                    onCursorActivity={onCursorActivity}
                                    className={"code-mirror"}
                                    value={rule.searchFind}
                                    options={codeMirrorOpt}
                                    onBeforeChange={(editor, data, value) => onChange("searchFind", value)}
                                    editorDidMount={editor => {
                                        sEditorRef.current = editor;
                                    }}
                                />
                            </div>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>二级解析：</h3><span>（列表;标题;图片;描述;链接）</span>
                            <div className={"code-mirror-bg"}>
                                <CodeMirror
                                    onCursorActivity={onCursorActivity}
                                    className={"code-mirror"}
                                    value={rule.detail_find_rule}
                                    options={codeMirrorOpt}
                                    onBeforeChange={(editor, data, value) => onChange("detail_find_rule", value)}
                                    editorDidMount={editor => {
                                        dEditorRef.current = editor;
                                    }}
                                />
                            </div>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>搜二解析：</h3><span>（列表;标题;图片;描述;链接）</span>
                            <div className={"code-mirror-bg"}>
                                <CodeMirror
                                    onCursorActivity={onCursorActivity}
                                    className={"code-mirror"}
                                    value={rule.sdetail_find_rule}
                                    options={codeMirrorOpt}
                                    onBeforeChange={(editor, data, value) => onChange("sdetail_find_rule", value)}
                                    editorDidMount={editor => {
                                        sdEditorRef.current = editor;
                                    }}
                                />
                            </div>
                        </div>
                        <div className={"mail-edit-head-bg"}>
                            <h3 className={"head-title"}>JS预处理：</h3><span>（解析规则和搜索解析规则前执行）</span>
                            <div className={"code-mirror-bg"}>
                                <CodeMirror
                                    onCursorActivity={onCursorActivity}
                                    className={"code-mirror"}
                                    value={rule.preRule}
                                    options={codeMirrorOpt}
                                    onBeforeChange={(editor, data, value) => onChange("preRule", value)}
                                    editorDidMount={editor => {
                                        editorRef.current = editor;
                                    }}
                                />
                            </div>
                        </div>
                    </div>
                </Panel>
            </div>
            <Modal
                okText={"导入"}
                cancelText={"取消"}
                title={"口令导入"}
                visible={ruleImportModalVisible}
                onCancel={() => setRuleImportModalVisible(false)}
                onOk={importRule}
            >
                <Input.TextArea
                    rows={20}
                    placeholder={"请输入口令，只能海阔视界开头"}
                    value={ruleImport}
                    onChange={(e) => setRuleImport(e.target.value)}/>
            </Modal>
            <Modal
                okText={"确定"}
                cancelText={"取消"}
                title={"请自行复制下面的口令"}
                visible={ruleShareModalVisible}
                onCancel={() => setRuleShareModalVisible(false)}
                onOk={() => setRuleShareModalVisible(false)}
            >
                <Input.TextArea
                    rows={20}
                    value={ruleShare}
                    onChange={(e) => setRuleShare(e.target.value)}/>
            </Modal>
            <ColTypeDrawer
                detailTypeShow={detailTypeShow}
                setDetailTypeShow={setDetailTypeShow}
                setFormN={setFormN}/>
        </div>
    );
}

export default RuleEdit;
